﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace FitAutomation.WPF
{
	public class SmartUpdateCollection<T> : ObservableCollection<T>
	{
		readonly Func<IEnumerable<T>> _fact;

		public SmartUpdateCollection(Func<IEnumerable<T>> fact)
		{
			_fact = fact;
			Update();
		}

		public void Update()
		{
			var items = _fact().ToArray();

			Action act = delegate
				{
					if (items.Length == 0 && Count != 0)
					{
						Clear();
					}
					else
					{
						for (int i = 0; i < items.Length; i++)
						{
							var item = items[i];
							if (Count - 1 < i)
							{
								Add(item);
							}
							if (!Equals(this[i], item))
							{
								if ((Count - 1) > i && Equals(this[i + 1], item))
								{
									// the next is ok - simply remove this
									RemoveAt(i);
								}
								else
								{
									// the next is bad too
									Insert(i, item);
								}
							}
						}
						for (int i = Count - 1; i >= items.Length; i--)
						{
							RemoveAt(i);
						}
					}
				};

			if (Application.Current != null && Application.Current.Dispatcher != null)
			{
				Application.Current.Dispatcher.BeginInvoke(act);
			}
			else
			{
				act();
			}
		}
	}
}